package cn.lic.tool.poi.excel.function.impl;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import cn.lic.tool.poi.excel.ParserUtils;
import cn.lic.tool.poi.excel.function.AbstractFunction;
import cn.lic.tool.poi.excel.function.FunctionParser;
import cn.lic.tool.poi.excel.function.IFunction;
import cn.lic.tool.poi.excel.function.IFunctionArgument;
import cn.lic.tool.poi.excel.function.IValue;
import cn.lic.tool.poi.excel.function.IValue.Type;
import cn.lic.tool.poi.excel.function.Range;
import cn.lic.tool.poi.excel.function.impl.grid.GridTplColumn;

/**
 * 生成表格
 * @author T_lichuang1_kzx
 *
 */
public class Grid extends AbstractFunction {
	
	private List<IGridListener> listeners = new ArrayList<IGridListener>();
	
	private LinkedList<GridTplColumn> tplColumnList = new LinkedList<>();
	
	public Grid() {}
	
	private Grid(IFunctionArgument[] args) {
		this.args = args;
	}
	/**
	 * @param args[0] 数据对象在context中的key
	 * @param args[1] 遍历影响的列数
	 */
	@Override
	public IFunction build(IFunctionArgument[] args) {
		return new Grid(args);
	}
	
	/**
	 * @param cell 函数所在单元格
	 * @param tplRow 模板行
	 * @return 
	 */
	@Override
	public Range execute(JSONObject ctx, Cell funCell) {
		
		JSONArray dataList = this.getArg(0, ctx).castValue(Type.JSON_ARRAY, IValue.EMPTY_ARRAY);
		int totalColumns = this.getArg(1, ctx).castValue(Type.INT, 0);

		// 函数行
		Row funRow = funCell.getRow();
		int rowStartIndex = funRow.getRowNum();
		Sheet sheet = funRow.getSheet();
		
		// 删除函数行
		sheet.shiftRows(rowStartIndex + 1, sheet.getLastRowNum(), -1, true, true);
		
		// 模板行
		Row tplRow = sheet.getRow(rowStartIndex);
		
		// 行指针，记录最后一行
		int rowEndIndex = tplRow.getRowNum();
		
		/* 渲染列区域 */
		int cellStartIndex = funCell.getColumnIndex();
		int cellEndIndex = tplRow.getLastCellNum();
		if (totalColumns > 0) {
			cellEndIndex = cellStartIndex + totalColumns;
		}
		int dataSize = dataList.size();
		
		beforeRender(ctx, tplRow, cellStartIndex, cellEndIndex);
		CellCopyPolicy	policy = new CellCopyPolicy().createBuilder().build();
		if (dataSize > 1) {
			sheet.shiftRows(rowEndIndex + 1, sheet.getLastRowNum(), dataSize - 1, true, true);
		}
		
		for (int i = 0; i < dataSize; i++) {
			Row currentRow = sheet.createRow(rowEndIndex);
			ParserUtils.copyRow(tplRow, currentRow, cellStartIndex, cellEndIndex, policy);
			
			JSONObject rowCtx = new JSONObject();
			rowCtx.putAll(ctx);
			rowCtx.put("[]", dataList.getJSONObject(i));
//			dataList.getJSONObject(i).entrySet().forEach(entry -> {
//				rowCtx.put("[]." + entry.getKey(), entry.getValue());
//			});
			
			parseRow(currentRow, cellStartIndex, cellEndIndex, rowCtx);
			
			rowEndIndex++;
		}
		
		if (dataSize > 0) {
			rowEndIndex--;
		}
		
		onEndRender(rowEndIndex);
		
		return new Range(rowStartIndex, rowEndIndex , cellStartIndex, cellEndIndex);
	}
	
	private void parseRow(final Row row, int startCellIndex, int endCellIndex, JSONObject rowCtx) {
		tplColumnList.iterator().forEachRemaining(fc->{
			Cell cell = row.getCell(fc.getColumnIndex());
			fc.getFun().execute(rowCtx, cell);
		});
//		for (int index = startCellIndex; index <= endCellIndex; index++) {
//			Cell cell = row.getCell(index);
//			if (cell == null || cell.getCellType() != CellType.STRING) {
//				continue;
//			}
//			
//			String template = cell.getStringCellValue();
//			IFunction fun = FunctionParser.getFunction(template);
//			if (fun != null) {
//				fun.execute(rowCtx, cell);
//			} else {
//				/*
//				 * 解析普通文本中包含的模板变量
//				 * */
//				StringBuffer sb = new StringBuffer();
//				Pattern pattern = Pattern.compile("\\$\\{[\\w+\\.\\[\\]]+\\}");
//				Matcher m = pattern.matcher(template);
//				while(m.find()) {
//					String group = m.group();
//					String key = group.substring(2, group.length() - 1);
//					Object val = null;
//					
//					if (FunctionParser.isFunction(key)) {
//						val = FunctionParser.getFunction(template).execute(rowCtx).get();
//					} else {
//						val = rowCtx.get(key);
//					}
//					m.appendReplacement(sb, String.valueOf(val));
//				}
//				
//				/*
//				 * 如果是常规字符串且没有变量，则不做赋值操作
//				 */
//				if (sb.length() > 0) {
//					m.appendTail(sb);
//					ParserUtils.setCellValue(cell, sb);
//				}
//			}
//		}
		
		onRenderRow(rowCtx,  row);
	}
	
//	/**
//	 * 拷贝行
//	 * @param srcRow
//	 * @param destIndex 拷贝行要插入的地址
//	 * @param policy
//	 */
//	private static Row copyRow(Row srcRow, Sheet destSheet, int destIndex, int cellStartIndex, int cellEndIndex) {
//		CellCopyPolicy	policy = new CellCopyPolicy().createBuilder().build();
//		destSheet.shiftRows(destIndex, destSheet.getLastRowNum(), 1, true, true);
//		Row destRow = destSheet.createRow(destIndex);
//		ParserUtils.copyRow(srcRow, destRow, cellStartIndex, cellEndIndex, policy);
//		return destRow;
//	}
	
	/**
	 * 解析模板中定义的监听函数
	 */
	private void beforeRender(JSONObject ctx, Row tplRow, int startCellIndex, int endCellIndex) {
		for (int i = startCellIndex; i <= endCellIndex ;i ++) {
			Cell cell = tplRow.getCell(i);
			if (cell == null || cell.getCellType() != CellType.STRING) {
				continue;
			}
			String template = cell.getStringCellValue();
			
			IFunction fun = FunctionParser.getFunction(template);
			if (fun != null && fun instanceof IGridListener) {
				IGridListener lis = (IGridListener)fun;
				lis.init(ctx, cell, tplRow.getSheet());
				listeners.add(lis);
				cell.setCellValue("");
			} else if (fun != null) {
				tplColumnList.add(new GridTplColumn(cell.getColumnIndex(), fun));
			}
		}
	}
	
	private void onRenderRow(JSONObject cellCtx,  Row row) {
		listeners.stream().forEach(lis -> {
			lis.renderRow(cellCtx, row);
		});
	}
	
	private void onEndRender(int rowEndIndex) {
		listeners.stream().forEach(lis -> {
			lis.endRender(rowEndIndex);
		});
	}

}
